<template>
  <div class="upload-main">
    <div class="upload-main-header">
      <div class="header-content flex">
        <el-input v-model="fileName"
          style="width: 250px; margin: 10px 20px 10px 20px"
          clearable
          :placeholder="placeholder"
          :suffix-icon="Search"
          @change="handleChange($event)" />
        <span class="flex">
          <el-icon style="margin-right: 5px">
            <InfoFilled style="color: #23abe0" />
          </el-icon>{{ `共${searchCount}个底稿文件` }}</span>
      </div>
    </div>
    <div id="mainContentId"
      class="upload-main-content topMargin bottomMargin leftMargin rightMargin">
      <div :class="isSearch ? 'upload-main-content-lf-hidden' : 'upload-main-content-lf rightMargin'">
        <div class="content-lf-contain">
          <el-tree style="padding: 10px"
            ref="elTreeRef"
            v-loading="fileLoadig"
            node-key="ruleId"
            :data="treeData"
            default-expand-all
            :props="defaultProps"
            :current-node-key="tempCurrentNodeKey"
            highlight-current
            @node-click="handleNodeClick">
            <template #default="{ node, data }">
              <span class="tree-content">
                <span class="tree-content-contain">
                  <span class="contain-star"
                    v-if="data.nullable === 'N'">*</span>
                  <span class="contain-lable"
                    :title="node.label">{{ node.label }}</span>
                  <el-icon v-if="data.status === 1"
                    class="contain-check">
                    <SuccessFilled />
                  </el-icon>
                </span>
              </span>
            </template>
          </el-tree>
        </div>
      </div>
      <div class="upload-main-content-rg">
        <div class="content-rg-contain">
          <div class="contet-rg-table">
            <rk-grid ref="rkGridRef"
              keyField="attachmentId"
              style="width: 100%"
              :boxConfig="false"
              :toolbarConfig="false"
              :dataUrl="'/uploadFile/list'"
              :params="fileParams"
              :pagerConfig="false"
              :columns="columns"
              @loaded="handleLoaded">
              <template #operation="{ row }">
                <div class="operation-box">
                  <el-button link
                    icon="View"
                    @click.stop="handleOptation(row, 'preview')"></el-button>
                  <el-button type="primary"
                    v-if="expertFileDownload"
                    link
                    icon="Download"
                    @click.stop="handleOptation(row, 'downLoad')"></el-button>
                  <template v-if="!deleteHidden">
                    <el-button type="danger"
                      link
                      icon="Delete"
                      @click.stop="handleOptation(row, 'delete')"></el-button>
                  </template>
                </div>
              </template>
            </rk-grid>
          </div>
          <div class="content-rg-file"
            v-if="selectData.ruleId && selectData.ruleId != '1' && !uploadHidden">
            <el-upload v-if="!uploadHidden"
              drag
              ref="uploadRef"
              v-loading="uploadLoading"
              :data="uploadParams"
              :action="uploadUrl"
              :headers="headers"
              :limit="1"
              :before-upload="beforeUpload"
              :on-exceed="handleOnExceed"
              :on-success="handleOnSuccess"
              :on-progress="handleOnProgress"
              :on-error="handleOnError">
              <el-icon class="el-icon--upload">
                <UploadFilled />
              </el-icon>
              <div class="el-upload__text">
                <em>你可以将文件拖拽到特定区域以进行上传。</em>
              </div>
              <template #tip>
                <div style="padding-top: 10px">
                  <div style="display: block; width: 100%; white-space: nowrap">
                    <p>
                      {{ `上传文件类型：${selectData.fileSuffix}` }}
                    </p>
                    <p>
                      {{ `上传文件大小：${FileUtils.formatDataFileSize(selectData.maxLimit)}` }}
                    </p>
                  </div>
                </div>
              </template>
            </el-upload>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup name="ChangeAttachmentPanel">
import { ref, reactive, watch, computed } from 'vue';
import { ElMessage, genFileId } from 'element-plus';
import { Search, SuccessFilled, InfoFilled, UploadFilled } from '@element-plus/icons-vue';

import XEUtils from 'xe-utils';
import FileUtils from '@/utils/file-utils';
import { AuthUtils } from '@/utils';

import { useFilesApi } from '@/api';
import { REQ_HEADER_KEY } from '@/utils/http/cfg/http-config';

import { useFileOptation } from '@/hooks/useFileHook'

const props = defineProps({
  //是否是在线评审预览
  isOnline: {
    type: [Boolean],
    default: false,
  },
  // 附件隐藏下载隐藏  true 不隐藏下载 false 隐藏下载
  expertFileDownload: {
    type: [Boolean],
    default: true,
  },
  title: {
    type: [String],
    default: '变更附件面板',
  },
  //规则类型
  busiType: {
    type: [String],
    default: '',
  },
  //业务ID
  busiId: {
    type: [String],
    default: '',
  },
  // 请求方式
  method: { type: String, default: 'post' },
  placeholder: {
    type: [String],
    default: '请输入文件名称',
  },
  defaultProps: {
    type: Object,
    default: () => ({
      children: 'children',
      label: 'fileDesc',
    }),
  },
  // 表单回显数据
  formData: { type: Object, default: () => ({}) },
  // 是否用于表单中
  useInForm: { type: Boolean, default: false },
  // 表单类型配置 add: 新增, edit:修改  atty:律所  acct:会所  finance:财评报告, yhs:一户式
  formType: { type: String, default: '' },
  slotDataHouse: { type: Object, default: () => ({}) },
});
const route = useRoute()
const routeQuery = useRoute().query
const fileLoadig = ref(false);
let uploadHidden = ref(false);
let deleteHidden = ref(true);
// add: 新增, atty:律所  acct:会所  finance:财评报告, 
let allArray = ['atty', 'acct', 'finance'];
// edit:修改
let editArray = ['edit'];
// yhs-一户式 supply-项目补录
let uploadHiddenArray = ['yhs', 'supply'];
watch(
  () => props.formType,
  (newValue) => {
    if (newValue) {
      if (allArray.includes(newValue)) {
        uploadHidden.value = false;
        deleteHidden.value = true;
      } else if (editArray.includes(newValue)) {
        uploadHidden.value = false;
        deleteHidden.value = false;
      } else if (uploadHiddenArray.includes(newValue)) {
        uploadHidden.value = true;
        deleteHidden.value = true;
      } else {
        uploadHidden.value = false;
        deleteHidden.value = false;
      }
    }
  },
  { deep: true, immediate: true }
);
onMounted(() => {
  if (props.formData.APPLY_ID) {
    const params = {
      busiId: props.formData.APPLY_ID,
      busiType: 'ET902',
    };
    getUploadFileRuleData(params);
    fileParams.value = {
      ...params,
    };
    uploadParams = {
      ...params,
    };
  }
});
const fileName = ref(null);
const isSearch = ref(false);
const searchCount = ref(0);
/**输入监听 */
const handleChange = (value) => {
  isSearch.value = value ? true : false;
  fileParams.value = {
    ...fileParams.value,
    fileName: fileName.value,
  };
  handleSearch();
};

// 树结构Ref对象
const elTreeRef = ref(null);
// 树结构数据
let treeData = reactive([]);
// 选择的左侧数据
let selectData = reactive({});
// 当前选中节点
const tempCurrentNodeKey = ref('1');
/**左侧树点击方法 */
const handleNodeClick = (data) => {
  if (tempCurrentNodeKey.value === data.ruleId) {
    return
  }
  tempCurrentNodeKey.value = data.ruleId;
  fileParams.value = {
    ...fileParams.value,
    ruleId: data.ruleId,
  };
  uploadParams = {
    ...uploadParams,
    ruleId: data.ruleId,
  };
  selectData = {
    ...data,
  };
  if (tempCurrentNodeKey.value === '1') {
    fileParams.value.fileName = undefined;
    fileParams.value.ruleId = undefined;
  }
  if (allArray.includes(props.formType)) {
    if (selectData.ruleId === props.formData.ruleId) {
      uploadHidden.value = false;
      deleteHidden.value = false;
    } else {
      uploadHidden.value = true;
      deleteHidden.value = true;
    }
  }
  handleSearch();
};
/**获取附件规则数据 */
const getUploadFileRuleData = async (params) => {
  fileLoadig.value = true;
  const queryParams = {
    ...params,
    busiProperty: '%',
    processKey: routeQuery.processKey
  };
  const result = await useFilesApi().uploadFileRuleData(queryParams);
  const { data, code, msg } = result;
  if (code === 200) {
    let model = [
      {
        ruleId: '1',
        fileDesc: '全部',
        children: [...data],
      },
    ];
    treeData = model;
    fileLoadig.value = false;
    if (tempCurrentNodeKey.value) {
      nextTick(() => {
        if (elTreeRef.value) elTreeRef?.value.setCurrentKey(tempCurrentNodeKey.value);
      });
    }
  } else {
    console.error(msg);
    fileLoadig.value = false;
  }
};

// 表格的Ref对象
const rkGridRef = ref(null);
// 表格的查询参数
const fileParams = ref({});
// 表格字段定义
const columns = ref([
  {
    field: 'operation',
    title: '操作',
    width: 150,
    showOverflow: true,
    align: 'center',
    slots: { default: 'operation' },
  },
  { field: 'fileName', title: '文件名称', align: 'left', width: 250, headerAlign: 'center' },
  { field: 'fileDesc', title: '附件类型', showOverflow: true, width: 200, align: 'left' },
  { field: 'fileType', title: '文件类型', showOverflow: true, width: 150, align: 'center' },
  {
    field: 'fileSize',
    title: '文件大小',
    showOverflow: true,
    width: 120,
    align: 'center',
    slots: {
      default: ({ row }) => {
        const fileSize = FileUtils.formatDataFileSize(row.fileSize);
        return fileSize;
      },
    },
  },
  { field: 'uploadTime', title: '上传时间', width: 200, showOverflow: true, align: 'center' },
]);
/**获取表格数据 */
const handleLoaded = (finalData) => {
  searchCount.value = finalData.length ?? 0;
  setSlotDataHouse()
};
/**重新获取数据 */
const handleSearch = (type = 'search') => {
  rkGridRef.value.searchEvent();
};
/**表格点击方法 */
const handleOptation = async (row, type) => {
  const { fileId, fileName } = row;
  if (type === 'preview') {
    useFileOptation().filePreview(fileId, fileName, props.isOnline)
  } else if (type === 'downLoad') {
    useFileOptation().fileDownload(fileId, fileName)
  } else if (type === 'delete') {
    useFileOptation().fileDelete(fileId).then(() => {
      handleSearch();
      getUploadFileRuleData({
        busiId: props.formData.APPLY_ID,
        busiType: 'ET902',
      });
    })
  }
};

// 上传组件的Ref
const uploadRef = ref('');
// 上传文件的文件头
const headers = computed(() => {
  const result = {
    t: +new Date()
  }
  // 验证token是否存在，并携带请求头
  const accessToken = AuthUtils.accessToken.get();
  if (!XEUtils.isEmpty(accessToken)) {
    result[REQ_HEADER_KEY] = accessToken;
  }
  return result
})
// 上传的参数
let uploadParams = reactive({});
// 上传的接口地址
const uploadUrl = import.meta.env.VITE_API_URL + '/uploadFile/file';
// 上传文件加载中
const uploadLoading = ref(false);
/**
 * 上传文件前做文件校验
 *
 * @param {Object} file 选择的文件
 */
const beforeUpload = (file) => {
  const suffixs = selectData.fileSuffix.replace(/\n/, '').split('/').map(item => item.replace(/^./, ''))
  const upSuffix = FileUtils.getFileSuffix(file.name)
  if (suffixs.includes(upSuffix)) {
    return true
  } else {
    ElMessage.warning(`【${file.name}】不符合上传类型，请重新选择！`)
    return false
  }
}
/**当超出限制时，执行的钩子函数 */
const handleOnExceed = (files) => {
  uploadRef.value.clearFiles();
  const file = files[0];
  file.uid = genFileId();
  uploadRef.value.handleStart(file);
};
/**上传文件中 */
const handleOnProgress = (evt, uploadFile, uploadFiles) => {
  uploadLoading.value = true;
  // console.log('上传中', evt, uploadFile, uploadFiles)
};
/**上传文件成功 */
const handleOnSuccess = async (response, uploadFile, uploadFiles) => {
  uploadLoading.value = false;
  // console.log('上传成功', response, uploadFile, uploadFiles)
  const { msg, code } = response;
  if (code === 200) {
    ElMessage({
      message: '文件上传成功！',
      center: true,
      type: 'success',
    });
  } else {
    ElMessage({
      message: msg + '！',
      center: true,
      type: 'error',
    });
  }
  rkGridRef.value.searchEvent();
  const params = {
    busiId: props.formData.APPLY_ID,
    busiType: 'ET902',
  };
  await getUploadFileRuleData(params);
  uploadRef.value.clearFiles();
};
/**上传文件失败 */
const handleOnError = (error, uploadFile, uploadFiles) => {
  console.log('上传失败', error, uploadFile, uploadFiles);
  uploadLoading.value = false;
  ElMessage({
    message: '文件上传失败！',
    center: true,
    type: 'error',
  });
  uploadRef.value.clearFiles();
};

// 设置附件数据
const setSlotDataHouse = () => {
  if (props.useInForm) {
    // ----- 表单的插槽数据空间操作
    const queryParams = {
      busiId: props.formData.APPLY_ID,
      busiType: 'ET902',
    };
    useFilesApi().getAllUploadFiles(queryParams)
      .then((res) => {
        const { code, data, msg } = res;
        if (code === 200) {
          props.slotDataHouse['AttachmentPanel'] = data;
        } else {
          props.slotDataHouse['AttachmentPanel'] = [];
        }
      })
      .catch((err) => {
        console.error(err);
      });
  }
};
</script>
<style lang="scss" scoped>
$borderColor: rgb(233, 233, 233);
$backgroundColor: rgb(233, 237, 246);
$whiteBackgroundColor: #fff;
:deep(.el-upload-dragger) {
	padding: 10px;
}
.vxe-toolbar {
	padding-top: 0;
}
.flex {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
}
.flexJustifyCenter {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: center;
}
.topPadding {
	padding-top: 10px;
}
.leftPadding {
	padding-left: 10px;
}
.rightPadding {
	padding-right: 10px;
}
.bottomPadding {
	padding-bottom: 10px;
}
.topMargin {
	margin-top: 10px;
}
.bottomMargin {
	margin-bottom: 10px;
}
.leftMargin {
	margin-left: 10px;
}
.rightMargin {
	margin-right: 10px;
}
.upload-main {
	width: 100%;
	height: 100%;
	background-color: $backgroundColor;
	.upload-main-header {
		width: 100%;
		background-color: $whiteBackgroundColor;
		.header-content {
			font-size: 14px;
			box-sizing: border-box;
		}
	}
	.upload-main-content {
		box-sizing: border-box;
		display: flex;
		flex-wrap: nowrap;
		box-sizing: border-box;
		height: calc(100% - 72px);
		overflow: hidden;
		.upload-main-content-lf-hidden {
			width: 0px;
		}
		.upload-main-content-lf {
			width: 300px;
			height: 100%;
			background-color: $whiteBackgroundColor;
			box-sizing: border-box;
			.content-lf-contain {
				box-sizing: border-box;
				border: 1px solid $borderColor;
				border-radius: 4px;
				height: 100%;
				overflow-y: scroll;
				.el-tree {
					overflow-y: hidden;
				}
				.tree-content {
					overflow: hidden;
					width: 100%;
					padding-top: 10px;
					padding-bottom: 10px;
					.tree-content-contain {
						width: 100%;
						display: flex;
						align-items: center;
						justify-content: space-between;
						.contain-star {
							position: absolute;
							color: red;
						}
						.contain-lable {
							flex: 1;
							padding-right: 10px;
							overflow: hidden;
							white-space: nowrap;
							text-overflow: ellipsis;
							-o-text-overflow: ellipsis;
						}
						.contain-check {
							color: #40c475;
						}
					}
				}
			}
		}
		.upload-main-content-rg {
			flex: 1;
			width: 0;
			height: 100%;
			background-color: $whiteBackgroundColor;
			box-sizing: border-box;
			z-index: 999;

			.content-rg-contain {
				display: flex;
				flex-direction: column;
				height: 100%;
				padding: 10px;
				.contet-rg-table {
					flex: 1;
					height: 0;
					width: 100%;
				}
				.content-rg-file {
					height: 200px;
					width: 100%;
					margin-top: 20px;
					background-color: $whiteBackgroundColor;
					border-radius: 4px;
					border: 1px dashed rgb(233, 233, 233);
					padding: 10px;
				}
			}
		}
	}
	.iframe {
		width: 100%;
		height: 100%;
	}
}
</style>
